﻿using System;
using SDTRace = System.Diagnostics.Trace;
using AzureContrib.WindowsAzure.Utils;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Description;
using Microsoft.ServiceBus.Messaging;
using Microsoft.ServiceBus.Messaging.Filters;

namespace AzureContrib.WindowsAzure.Diagnostics
{
	/// <summary>
	/// A client which can read the trace sent over <see cref="Microsoft.ServiceBus"/> from the <see cref="ServiceBusTraceListener"/>
	/// </summary>
	public class ServiceBusTraceListenerClient
	{
		/// <summary>
		/// The setting name for the issuer secret used in the ServiceBus by <see cref="ServiceBusTraceListener"/>.
		/// </summary>
		public const string ServiceBusIssuerSecretSettingName = "IssuerSecret for ServiceBusTraceListener";

		/// <summary>
		/// Fish through the <see cref="IAppSettings"/> and make sure we are set to actually attach this listener. If so then attach!
		/// </summary>
		public ServiceBusTraceListenerClient(IAppSettings appSettings)
		{
			string serviceNamespace;
			if (!appSettings.TryGetConfigurationSettingValue(ServiceBusTraceListener.ServiceBusNameSpaceSettingName, out serviceNamespace))
			{
				SDTRace.Fail("The configuration setting named '{0}' is not present. Not able to start the {1}!".F(ServiceBusTraceListener.ServiceBusNameSpaceSettingName, GetType().FullName));
				return;
			}

			Uri serviceBusUri = ServiceBusEnvironment.CreateServiceUri("sb", serviceNamespace, String.Empty);

			string issuerName;
			if (!appSettings.TryGetConfigurationSettingValue(ServiceBusTraceListener.ServiceBusNameSpaceSettingName, out issuerName))
			{
				SDTRace.Fail("The configuration setting named '{0}' is not present. Not able to start the {1}!".F(ServiceBusTraceListener.ServiceBusIssuerNameSettingName, GetType().FullName));
				return;
			}

			string issuerKey;
			if (!appSettings.TryGetConfigurationSettingValue(ServiceBusIssuerSecretSettingName, out issuerKey))
			{
				SDTRace.Fail("The configuration setting named '{0}' is not present. Not able to start the {1}!".F(ServiceBusTraceListener.ServiceBusIssuerNameSettingName, GetType().FullName));
				return;
			}

			SharedSecretCredential sharedSecretCredential = TransportClientCredentialBase.CreateSharedSecretCredential(issuerName, issuerKey);

			var serviceBusNamespaceClient = new ServiceBusNamespaceClient(serviceBusUri, sharedSecretCredential);

			var topicName = "TopicsWithRulesQueue";
			if (appSettings.TryGetConfigurationSettingValue(ServiceBusTraceListener.ServiceBusTopicSettingName, out topicName))
			{
				SDTRace.Fail("The configuration setting named '{0}' is not present. Not able to start the {1}!".F(ServiceBusTraceListener.ServiceBusTopicSettingName, GetType().FullName));
				return;
			}
			try
			{
				serviceBusNamespaceClient.DeleteTopic(topicName);
			}
			catch (MessagingEntityNotFoundException)
			{ }
			Topic topic = serviceBusNamespaceClient.CreateTopic(topicName);

			// Create a Rule that selectively stamps Priority and Imporance values
			var ruleDescription = new RuleDescription
			{
				FilterExpression = new SqlFilterExpression("SupportPackage = 'Premium' OR Severity <= 1"),
				FilterAction = new SqlFilterAction("set Priority = 1;set Importance = 'High';")
			};

			// Create a Subscription and apply rule
			Subscription subscription = topic.AddSubscription("IssueTrackingSubscription", ruleDescription);
		}
	}
}